package cn.dark.auth.ssoserver.controller;

import cn.dark.auth.core.LoginCore;
import cn.dark.auth.core.exception.AuthBaseException;
import cn.dark.auth.core.repository.LoginRepository;
import cn.dark.auth.ssoserver.util.SpringMvcUtils;
import cn.hutool.extra.spring.SpringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;

/**
 * @author dark
 * @date 2023-10-29
 */
@RestController
public class SsoServerController {

    @GetMapping("/auth")
    public Object auth() throws IOException {
        String token = SpringMvcUtils.getToken();
        if (!LoginCore.isLogin(token)) {
            return new ModelAndView("login.html");
        }

        String redirect = SpringMvcUtils.getRequest().getParameter("redirect");
        if (StringUtils.isBlank(redirect)) {
            throw new AuthBaseException("回调地址不存在");
        }

        // todo ticket唯一校验
        Long loginId = LoginCore.getLoginIdByToken(token);
        String ticket = UUID.randomUUID().toString();

        LoginRepository loginRepository = SpringUtil.getBean(LoginRepository.class);
        loginRepository.saveObject("auth.sso.ticket:" + ticket, loginId, 5 * 60);

        // todo 回调地址是否合法
        redirect = joinParam(redirect, "ticket=" + ticket);
        HttpServletResponse response = SpringMvcUtils.getResponse();
        response.sendRedirect(redirect);
        return null;
    }

    @GetMapping("/doLogin")
    public String doLogin(@RequestParam("userId") Long userId,
                          @RequestParam("password") String password) {
        if (!LoginCore.isLogin(SpringMvcUtils.getToken())) {
            return LoginCore.login(userId);
        }

        return LoginCore.getTokenByUserId(userId, null);
    }

    @GetMapping("/getUserIdByTicket")
    public Long getUserIdByTicket(@RequestParam("ticket") String ticket) {
        LoginRepository loginRepository = SpringUtil.getBean(LoginRepository.class);
        return (Long) loginRepository.getObject("auth.sso.ticket:" + ticket);
    }

    public static String joinParam(String url, String paramStr) {
        // 如果参数为空, 直接返回
        if(paramStr == null || paramStr.length() == 0) {
            return url;
        }
        if(url == null) {
            url = "";
        }
        int index = url.lastIndexOf('?');
        // ? 不存在
        if(index == -1) {
            return url + '?' + paramStr;
        }
        // ? 是最后一位
        if(index == url.length() - 1) {
            return url + paramStr;
        }
        // ? 是其中一位
        if(index < url.length() - 1) {
            String separatorChar = "&";
            // 如果最后一位是 不是&, 且 paramStr 第一位不是 &, 就赠送一个 &
            if(url.lastIndexOf(separatorChar) != url.length() - 1 && paramStr.indexOf(separatorChar) != 0) {
                return url + separatorChar + paramStr;
            } else {
                return url + paramStr;
            }
        }
        // 正常情况下, 代码不可能执行到此
        return url;
    }

}
